// token
var jsonwebtoken = require('jsonwebtoken')
var { secret } = require('../config')
const svgCaptcha = require('svg-captcha');  //验证码插件
// 用户
var Users = require('../models/Users')
// 提问
// 答案
const { ResultCodeEnumConst } = require('../utils/ResultCodeEnum')
const R = require('../utils/R')
const { generateToken } = require('../controllers/middleware')
/*
获取HTTP请求参数
* query string  可选 ?q=keyword  ctx.query
* router params 必选 /users/:id  ctx.params
* body {name:'王家辉'}           ctx.request.body
*
响应头信息
* status 200/400
* body {name:'王家辉'}
* header allow content-type
*
* */
class UserCtl {
    async testLogin(ctx) {
        ctx.body = 'hello'
        // console.log(ctx.query)
    }


    async getCaptcha(ctx) {
        // 字母验数字证码
        let codeConfig = {
            size: 4,// 验证码长度
            ignoreChars: '0o1i', // 验证码字符中排除 0o1i
            noise: 5, // 干扰线条的数量
            width: 100, //验证码宽度
            height: 40, //验证码高度
            fontSize: 40,   //字体大小
            color: true,    //开启字体颜色
            background: '#cc9966',//背景颜色
            // charPreset:'abcd123456789', //随机预设字符
        }
        let captcha = svgCaptcha.create(codeConfig); //验证码
        // 将验证码结果字符串存入session中
        ctx.app.captcha = captcha.text
        //  直接返回svg格式,需要img标签展示
        ctx.type = 'svg'
        // 如不,则需要innerHTML写入标签
        ctx.body = captcha.data


        // 数学表算式验证码
        // let codeConfig = {
        //   mathMin: 1, //数学表达式的最小值
        //   mathMax: 20, // 数学表达式的最大值
        //   mathOperator: '+', // 使用的运算符:+、-或+-(用于随机的+或-)
        //   noise: 5, // 干扰线条的数量
        //   width: 100, //验证码宽度
        //   height: 40, //验证码高度
        //   fontSize: 40,   //字体大小
        //   color: true,    //开启字体颜色
        //   background: '#cc9966',//背景颜色
        // }
        // let captcha = svgCaptcha.createMathExpr(codeConfig); //算式验证码
        // //captcha.text 验证码的文字码
        // //captcha.data 验证码图片的svg数据
        // ctx.body = captcha
    }



    async find(ctx) {
        // 每页条数
        const perPage = parseInt(ctx.query.perPage) || 10
        // 当前页
        const page = parseInt(ctx.query.page) || 1
        // 跳过条数
        const skip = (page - 1) * perPage
        // 分页 模糊搜索
        const q = new RegExp(ctx.query.q)
        // 倒序
        const list = await Users.find({ user_name: q }).limit(perPage).skip(skip).sort({ createdAt: -1 })
        // 总条数
        const total = await Users.find({ user_name: q }).countDocuments()
        // 向上取整 一共有多少页
        const totalPage = Math.ceil(total / perPage)
        ctx.body = R.ok().data({
            data: list,
            page,
            perPage,
            total,
            totalPage,
        })
    }

    async findById(ctx) {
        // http://localhost:3000/users/5e48e26bfb874d2f6ca2ace7?fields=introduction
        // ?fields后面写上指定的参数，即可查询并返回指定的字段
        const { fields = '' } = ctx.query
        // fields可能是一个空字符串，需要使用filter过滤一下
        // 这following;locations;business三个字段即可可以正常查询
        const selectFields = fields.split(';').filter(f => f).map(f => ' +' + f).join('')
        console.log(selectFields);
        // populateStr进行深度查询，获取employments;educations中的对象
        const populateStr = fields.split(';').filter(f => f).map(f => {
            if (f === 'employments') {
                return 'employments.company employments.job'
            }
            if (f === 'educations') {
                return 'educations.school educations.major'
            }
            return f
        }).join(' ')
        console.log(populateStr);
        // 显示selectFields、populateStr中的字段，但里面只有id，根据id查询用户字段里的具体信息，需要集合联合查询
        var user = await Users.findById(ctx.params.id).select(selectFields).populate(populateStr)
        if (!user) ctx.throw(404, '此用户不存在')
        ctx.body = R.ok().data({ data: user })
    }

    async create(ctx) {
        // 验证 用户名、密码是必须的，所以required为true
        ctx.verifyParams({
            name: { type: 'string', required: true },
            password: { type: 'string', required: true },
            avatar_url: { type: 'string', required: false },
            gender: { type: 'enum', required: false },
            headline: { type: 'string', required: false }
        })
        const { name } = ctx.request.body
        const repeatedUser = await Users.findOne({ name })
        if (repeatedUser) return ctx.throw(409, '此用户已被占用')
        var user = await new Users(ctx.request.body).save()
        ctx.body = R.ok().data({ data: user })

        // var user = Users.create(ctx.request.body)
        // ctx.body = user
    }

    // 此用户已存在中间件(暂不需要)
    async checkUser(ctx, next) {
        const { name } = ctx.request.body
        const repeatedUser = await Users.findOne({ name })
        if (repeatedUser) {
            ctx.throw(409, '此用户已被占用')
        } else {
            next()
        }
    }

    // 授权处理中间件
    async checkOwner(ctx, next) {
        // 已经登录就有ctx.state.user字段
        if (ctx.params.id !== ctx.state.user._id) {
            ctx.throw(403, '没有权限', ctx.state.user)
        } else {
            await next()
        }
    }

    async update(ctx) {
        ctx.verifyParams({
            name: { type: 'string', required: false },
            password: { type: 'string', required: false },
            avatar_url: { type: 'string', required: false },
            gender: { type: 'string', required: false },
            headline: { type: 'string', required: false },
            locations: { type: 'array', itemType: 'string', required: false },
            business: { type: 'string', required: false },
            employments: { type: 'array', itemType: 'object', required: false },
            educations: { type: 'array', itemType: 'object', required: false },
        })
        var user = await Users.findByIdAndUpdate(ctx.params.id, ctx.request.body, {
            new: true
        })
        if (!user) ctx.throw(404, '此用户不存在')
        ctx.body = R.ok().data({ data: user })
        // 注：返回的是更新前的user，mongoose的findByIdAndUpdate语法问题，待优化
        // 已解决
        // {
        //     new: true
        // }
        // {
        //     "avatar_url":"http://localhost:3000/uploads/upload_bc234b04a43c94b38bee7142c5076ad2.png",
        //     "gender":"male",
        //     "headline":"天地滂沱如何渡？蓑衣褪尽任浊流。",
        //     "localtions":["5e58898d42a9f10340e2bdc4"],
        //     "business":"5e58d169bc818009cc427bac",
        //     "employments":[{"company":"5e58898d42a9f10340e2bdc4","job":"5e58897642a9f10340e2bdc1"}],
        //     "educations":[{"school":"5e58898a42a9f10340e2bdc3","major":"5e58893a42a9f10340e2bdc0"}]
        // }
        // 话题引用了用户，所以更新的时候需要传话题的id，即可关联
    }

    async remove(ctx) {
        var user = await Users.findByIdAndRemove(ctx.params.id)
        if (!user) ctx.throw(404, '此用户不存在')
        ctx.body = { message: '删除成功' }
    }

    async login(ctx) {
        // 验证 用户名、密码是必须的，所以required为true
        ctx.verifyParams({
            mobile: { type: 'string', required: true },
            mobile_code: { type: 'string', required: false },
            user_name: { type: 'string', required: false },
            // 验证码
            // auth_code: { type: 'number', required: false },
        })
        const { mobile, user_name } = ctx.request.body
        if (!user_name) {
            ctx.request.body.user_name = mobile
        }
        let user = null
        let token = ''
        user = await Users.findOne({ mobile })
        if (user) {
            // 存在登录
            token = await generateToken({
                _id: user.id,
                mobile_code: user.mobile_code
            })
        } else {
            // 否则注册登录
            user = await new Users(ctx.request.body).save()
            if (user) {
                token = await generateToken({
                    _id: user.id,
                    mobile_code: user.mobile_code
                })
            }
        }
        const data = {
            ...user._doc,
            token,
            ctx
        }
        ctx.body = R.ok().data(data)
    }


}

module.exports = new UserCtl()
